package aiku.numericalcontroloa.Service.Impl;

import aiku.numericalcontroloa.Base.Utils.HttpStatus;
import aiku.numericalcontroloa.Base.Utils.Result;
import aiku.numericalcontroloa.Mapper.PaymentBillingMapper;
import aiku.numericalcontroloa.Mapper.PurchaseOrdersMapper;
import aiku.numericalcontroloa.Mapper.RemarksMapper;
import aiku.numericalcontroloa.Model.Dto.SuppliersDto;
import aiku.numericalcontroloa.Model.Entity.PaymentBilling;
import aiku.numericalcontroloa.Model.Entity.PurchaseOrders;
import aiku.numericalcontroloa.Model.Entity.Remarks;
import aiku.numericalcontroloa.Model.Vo.SuppliersVo;
import aiku.numericalcontroloa.Service.SuppliersService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import aiku.numericalcontroloa.Model.Entity.Suppliers;
import aiku.numericalcontroloa.Mapper.SuppliersMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 马
 * @description 针对表【suppliers】的数据库操作Service实现
 * @createDate 2024-02-23 16:15:06
 */
@Service
public class SuppliersServiceImpl extends ServiceImpl<SuppliersMapper, Suppliers>
        implements SuppliersService {

    @Autowired
    private SuppliersMapper suppliersMapper;

    private final RemarksMapper remarksMapper;
    private final PaymentBillingMapper paymentBillingMapper;
    private final PurchaseOrdersMapper purchaseOrdersMapper;

    public SuppliersServiceImpl(RemarksMapper remarksMapper, PaymentBillingMapper paymentBillingMapper,
            PurchaseOrdersMapper purchaseOrdersMapper) {
        this.remarksMapper = remarksMapper;
        this.paymentBillingMapper = paymentBillingMapper;
        this.purchaseOrdersMapper = purchaseOrdersMapper;
    }

    /**
     * 添加供应商
     * 
     * @param supplier
     * @return
     */
    @Override
    public Result add(Suppliers supplier) {
        // TODO: 权限是否添加还未确定
        // 查询供应商是否存在
        LambdaQueryWrapper<Suppliers> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Suppliers::getSuppliersName, supplier.getSuppliersName())
                .eq(Suppliers::getSuppliersAddress, supplier.getSuppliersAddress())
                .eq(Suppliers::getSuppliersPhone, supplier.getSuppliersPhone());
        Suppliers suppliers = suppliersMapper.selectOne(queryWrapper);
        if (suppliers != null) {
            return Result.error(201, "供应商已存在");
        }
        // 添加供应商
        int insert = suppliersMapper.insert(supplier);
        return insert > 0 ? Result.success("添加成功") : Result.error("添加失败");
    }

    @Override
    public Result getSuppliersList(SuppliersDto suppliersDto) {
        if (suppliersDto == null || (suppliersDto.getCurrentPage() == null || suppliersDto.getPageSize() == null)) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        Page<Suppliers> suppliersPage = new Page<>(suppliersDto.getCurrentPage(), suppliersDto.getPageSize());
        // 条件查询
        LambdaQueryWrapper<Suppliers> suppliersLQW = new LambdaQueryWrapper<>();
        suppliersLQW.orderByDesc(Suppliers::getCreateTime);
        // 根据省
        if (suppliersDto.getProvince() != null && suppliersDto.getCity() == null
                && suppliersDto.getDistrict() == null) {
            suppliersLQW.eq(Suppliers::getProvince, suppliersDto.getProvince());
        } else if (suppliersDto.getProvince() != null && suppliersDto.getCity() != null
                && suppliersDto.getDistrict() == null) {
            suppliersLQW.eq(Suppliers::getProvince, suppliersDto.getProvince())
                    .eq(Suppliers::getCity, suppliersDto.getCity());
        } else if (suppliersDto.getProvince() != null && suppliersDto.getCity() != null
                && suppliersDto.getDistrict() != null) {
            suppliersLQW.eq(Suppliers::getProvince, suppliersDto.getProvince())
                    .eq(Suppliers::getCity, suppliersDto.getCity())
                    .eq(Suppliers::getDistrict, suppliersDto.getDistrict());
        }
        // 根据名称，电话，地址模糊查询
        if (suppliersDto.getSuppliersName() != null && !suppliersDto.getSuppliersName().isEmpty()) {
            suppliersLQW.and(s -> s.like(Suppliers::getSuppliersName, suppliersDto.getSuppliersName())
                    .or().like(Suppliers::getSuppliersPhone, suppliersDto.getSuppliersName())
                    .or().like(Suppliers::getSuppliersAddress, suppliersDto.getSuppliersName()));
        }
        // List<Suppliers> suppliersList =
        // suppliersMapper.selectPage(suppliersPage,suppliersLQW).getRecords();
        List<Suppliers> suppliersList = suppliersMapper.selectList(suppliersLQW);
        Map<String, Object> map = new HashMap<>();
        List<SuppliersVo> suppliersVoList = new ArrayList<>();
        if (suppliersList.isEmpty()) {
            map.put("total", 0);
            map.put("suppliersVoList", suppliersVoList);
            return Result.success("查询成功", map);
        }
        // 根据供应商id查询备注列表
        List<String> suppliersIdList = suppliersList.stream().map(Suppliers::getId).collect(Collectors.toList());
        LambdaQueryWrapper<Remarks> remarksLQW = new LambdaQueryWrapper<>();
        remarksLQW.in(Remarks::getQueryId, suppliersIdList);
        List<Remarks> remarksList = remarksMapper.selectList(remarksLQW);
        // 将id和内容以键值形式存入map中
        Map<String, String> remarksMap = remarksList.stream()
                .collect(Collectors.toMap(Remarks::getQueryId, Remarks::getRemarkContent));

        // 查本月所有未付款账单
        LambdaQueryWrapper<PaymentBilling> paymentBillingLQW = new LambdaQueryWrapper<>();
        paymentBillingLQW.ne(PaymentBilling::getBillsStatus, 1)
                .apply("DATE_FORMAT(date_payable, '%Y-%m') = {0}", YearMonth.now());
        List<PaymentBilling> billingList = paymentBillingMapper.selectList(paymentBillingLQW);
        // 拿采购订单id列表
        List<String> orderIdList = new ArrayList<>();
        if (billingList.isEmpty()) {
            orderIdList.add("");
        } else {
            orderIdList = billingList.stream().map(PaymentBilling::getOrderId).collect(Collectors.toList());
        }
        // 查月结采购订单
        LambdaQueryWrapper<PurchaseOrders> purchaseOrdersLQW = new LambdaQueryWrapper<>();
        purchaseOrdersLQW.in(PurchaseOrders::getId, orderIdList).eq(PurchaseOrders::getPaymentMethod, 1);
        List<PurchaseOrders> purchaseOrdersList = purchaseOrdersMapper.selectList(purchaseOrdersLQW);
        // 根据供应商id获取采购订单集合
        Map<String, List<PurchaseOrders>> purchaseOrdersMap = new HashMap<>();
        for (PurchaseOrders purchaseOrders : purchaseOrdersList) {
            if (purchaseOrdersMap.containsKey(purchaseOrders.getSuppliersId())) {
                purchaseOrdersMap.get(purchaseOrders.getSuppliersId()).add(purchaseOrders);
            } else {
                List<PurchaseOrders> ordersList = new ArrayList<>();
                ordersList.add(purchaseOrders);
                purchaseOrdersMap.put(purchaseOrders.getSuppliersId(), ordersList);
            }
        }

        for (Suppliers suppliers : suppliersList) {
            SuppliersVo suppliersVo = new SuppliersVo();
            BeanUtils.copyProperties(suppliers, suppliersVo);
            // 获取备注内容
            suppliersVo.setRemark(remarksMap.get(suppliers.getId()));
            // 月结账单数
            int billingTotal = 0;
            if (purchaseOrdersMap.containsKey(suppliers.getId())) {
                billingTotal = purchaseOrdersMap.get(suppliers.getId()).size();
            }
            suppliersVo.setBillingTotal(billingTotal);
            suppliersVoList.add(suppliersVo);
        }

        LambdaQueryWrapper<PaymentBilling> pBLQW = new LambdaQueryWrapper<>();
        pBLQW.ne(PaymentBilling::getBillsStatus, 1);
        List<PaymentBilling> billingLists = paymentBillingMapper.selectList(pBLQW);
        // 拿采购订单id列表
        List<String> orderIdLists = new ArrayList<>();
        if (billingLists.isEmpty()) {
            orderIdLists.add("");
        } else {
            orderIdLists = billingLists.stream().map(PaymentBilling::getOrderId).collect(Collectors.toList());
        }
        // 查月结采购订单
        LambdaQueryWrapper<PurchaseOrders> pOLQW = new LambdaQueryWrapper<>();
        pOLQW.in(PurchaseOrders::getId, orderIdLists).eq(PurchaseOrders::getPaymentMethod, 1);
        List<PurchaseOrders> pOList = purchaseOrdersMapper.selectList(pOLQW);
        // 根据供应商id获取采购订单集合
        Map<String, List<PurchaseOrders>> pOMap = new HashMap<>();
        for (PurchaseOrders purchaseOrders : pOList) {
            if (pOMap.containsKey(purchaseOrders.getSuppliersId())) {
                pOMap.get(purchaseOrders.getSuppliersId()).add(purchaseOrders);
            } else {
                List<PurchaseOrders> ordersLists = new ArrayList<>();
                ordersLists.add(purchaseOrders);
                pOMap.put(purchaseOrders.getSuppliersId(), ordersLists);
            }
        }

        for (Suppliers suppliers : suppliersList) {
            BigDecimal totalAmount = new BigDecimal("0");
            if (pOMap.containsKey(suppliers.getId())) {
                totalAmount = pOMap.get(suppliers.getId()).stream().map(PurchaseOrders::getPrice)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            System.out.println(totalAmount);
            suppliersVoList.stream().filter(item -> item.getId().equals(suppliers.getId())).findAny().get()
                    .setTotalAmount(totalAmount);
        }

        int listLength = suppliersVoList.size();
        int selectPageStart = (int) ((suppliersPage.getCurrent() - 1) * suppliersPage.getSize());
        int selectPageEnd = (int) (suppliersPage.getCurrent() * suppliersPage.getSize());
        if (selectPageEnd > listLength) {
            selectPageEnd = listLength;
        }
        List<SuppliersVo> newList = suppliersVoList.stream()
                .sorted(Comparator.comparing(SuppliersVo::getBillingTotal).thenComparing(SuppliersVo::getTotalAmount).reversed())
                .collect(Collectors.toList())
                .subList(selectPageStart, selectPageEnd);

        map.put("total", listLength);
        map.put("suppliersVoList", newList);
        return Result.success("查询成功", map);
    }

    @Override
    @Transactional
    public Result addSuppliers(SuppliersDto suppliersDto) {
        if (suppliersDto == null) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        // 根据电话号码查询是否有该供应商
        LambdaQueryWrapper<Suppliers> suppliersLQW = new LambdaQueryWrapper<>();
        suppliersLQW.eq(Suppliers::getSuppliersPhone, suppliersDto.getSuppliersPhone());
        Suppliers suppliers = suppliersMapper.selectOne(suppliersLQW);
        if (suppliers != null) {
            return new Result(HttpStatus.BAD_REQUEST, "已有该供应商");
        }
        suppliers = new Suppliers();
        // 设置供应商名称
        if (suppliersDto.getSuppliersName() == null || suppliersDto.getSuppliersName().isEmpty()) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        suppliers.setSuppliersName(suppliersDto.getSuppliersName());
        // 设置联系电话
        if (suppliersDto.getSuppliersPhone() == null || suppliersDto.getSuppliersPhone().isEmpty()) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        suppliers.setSuppliersPhone(suppliersDto.getSuppliersPhone());
        // 设置省市区
        if (suppliersDto.getProvince() == null || suppliersDto.getCity() == null
                || suppliersDto.getDistrict() == null) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        // 判断省最后是否有‘市’字符，有则剔除
        if (suppliersDto.getProvince().endsWith("市")) {
            suppliersDto.setProvince(suppliersDto.getProvince().substring(0, suppliersDto.getProvince().length() - 1));
        }
        suppliers.setProvince(suppliersDto.getProvince());
        suppliers.setCity(suppliersDto.getCity());
        suppliers.setDistrict(suppliersDto.getDistrict());
        // 设置地址
        if (suppliersDto.getSuppliersAddress() == null || suppliersDto.getSuppliersAddress().isEmpty()) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        suppliers.setSuppliersAddress(suppliersDto.getSuppliersAddress());
        // 插入数据
        suppliersMapper.insert(suppliers);

        // 设置备注
        if (suppliersDto.getRemark() != null) {
            Remarks remarks = new Remarks();
            remarks.setQueryId(suppliers.getId());
            remarks.setRemarkContent(suppliersDto.getRemark());
            remarksMapper.insert(remarks);
        }
        return Result.success("添加成功");
    }

    @Override
    public Result getSuppliers(SuppliersDto suppliersDto) {
        if (suppliersDto == null || suppliersDto.getId() == null || suppliersDto.getId().isEmpty()) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        // 查询是否有该供应商
        Suppliers suppliers = suppliersMapper.selectById(suppliersDto.getId());
        if (suppliers == null) {
            return new Result(HttpStatus.BAD_REQUEST, "该供应商不存在");
        }
        SuppliersVo suppliersVo = new SuppliersVo();
        BeanUtils.copyProperties(suppliers, suppliersVo);
        // 查询备注
        LambdaQueryWrapper<Remarks> remarksLQW = new LambdaQueryWrapper<>();
        remarksLQW.eq(Remarks::getQueryId, suppliers.getId());
        Remarks remarks = remarksMapper.selectOne(remarksLQW);
        if (remarks != null) {
            suppliersVo.setRemark(remarks.getRemarkContent());
        }
        return Result.success("查询成功", suppliersVo);
    }

    @Override
    public Result getSuppliersWithDelete(SuppliersDto suppliersDto) {
        if (suppliersDto == null || suppliersDto.getId() == null || suppliersDto.getId().isEmpty()) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        // 查询是否有该供应商
        Suppliers suppliers = suppliersMapper.selectByIdWithDelete(suppliersDto.getId());
        if (suppliers == null) {
            return new Result(HttpStatus.BAD_REQUEST, "该供应商不存在");
        }
        SuppliersVo suppliersVo = new SuppliersVo();
        BeanUtils.copyProperties(suppliers, suppliersVo);
        // 查询备注
        LambdaQueryWrapper<Remarks> remarksLQW = new LambdaQueryWrapper<>();
        remarksLQW.eq(Remarks::getQueryId, suppliers.getId());
        Remarks remarks = remarksMapper.selectOne(remarksLQW);
        if (remarks != null) {
            suppliersVo.setRemark(remarks.getRemarkContent());
        }
        return Result.success("查询成功", suppliersVo);
    }

    @Override
    public Result deleteSuppliers(SuppliersDto suppliersDto) {
        if (suppliersDto == null || suppliersDto.getId() == null) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        // 查询是否有该供应商
        Suppliers suppliers = suppliersMapper.selectById(suppliersDto.getId());
        if (suppliers == null) {
            return new Result(HttpStatus.BAD_REQUEST, "该供应商不存在");
        }
        // 删除供应商
        suppliersMapper.deleteById(suppliersDto.getId());
        return Result.success("删除成功");
    }

    @Override
    @Transactional
    public Result updateSuppliers(SuppliersDto suppliersDto) {
        if (suppliersDto == null || suppliersDto.getId() == null) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        // 查询是否有该供应商
        Suppliers suppliers = suppliersMapper.selectById(suppliersDto.getId());
        if (suppliers == null) {
            return new Result(HttpStatus.BAD_REQUEST, "该供应商不存在");
        }
        BeanUtils.copyProperties(suppliersDto, suppliers);
        suppliersMapper.updateById(suppliers);

        if (suppliersDto.getRemark() != null) {
            // 查询是否有备注
            LambdaQueryWrapper<Remarks> remarksLQW = new LambdaQueryWrapper<>();
            remarksLQW.eq(Remarks::getQueryId, suppliers.getId());
            Remarks remarks = remarksMapper.selectOne(remarksLQW);
            if (remarks == null) {
                remarks = new Remarks();
                // 新增
                remarks.setQueryId(suppliers.getId());
                remarks.setRemarkContent(suppliersDto.getRemark());
                remarksMapper.insert(remarks);
            } else {
                // 修改
                remarks.setRemarkContent(suppliersDto.getRemark());
                LambdaUpdateWrapper<Remarks> remarksLUW = new LambdaUpdateWrapper<>();
                remarksLUW.eq(Remarks::getId, remarks.getId())
                        .set(Remarks::getRemarkContent, remarks.getRemarkContent());
                remarksMapper.update(null, remarksLUW);
            }
        }
        return Result.success("修改成功");
    }
}
